(function(c){ if(!c.testsLib){ c.testsLib = []; } })(this);
   
(function (){
    var test = { 
        name : "jsCSV structure test",
        code : function (){
                equal (typeof jsCSV, "function", "jsCSV is a function");
                equal (typeof jsCSV.parse, "function", "jsCSV.parse is a function");
                equal (typeof jsCSV.open, "function", "jsCSV.open is a function");
                equal (typeof jsCSV.write, "function", "jsCSV.write is a function");
                equal (typeof jsCSV.close, "function", "jsCSV.close is a function");

                var csvp = new jsCSV();
                equal (typeof csvp, "object", "csvp is an object");
                equal (typeof csvp.write, "function", "csvp has 'write' method");
                equal (typeof csvp.close, "function", "csvp has 'close' method");
        }
    };
    testsLib.push(test); //comment this line to remove from the test
})();    

(function (){
    function tokenize(test){
        var csv = jsCSV.open(test);
        jsCSV.write(csv,test);
        delete csv.input.buffer;
        return csv.input;
    }
    var test = { 
        name : "jsCSV procedural interface test",
        code : function (){

                var tests = {
                    "empty string" : {
                        test : "", 
                        expected : {tokens:[],index:0,reminder:""}, 
                        code:tokenize
                    },
                    "wrong string end" : {
                        test : "abc\",", 
                        expected : {tokens:[0,3],index:3,reminder:"\","}, 
                        code:tokenize
                    },
                    "wrong string start" : {
                        test : "\"abc", 
                        expected : {tokens:[],index:0,reminder:"\"abc"}, 
                        code:tokenize
                    },
                    "wrong string start 2" : {
                        test : "\"a", 
                        expected : {tokens:[],index:0,reminder:"\"a"}, 
                        code:tokenize
                    },
                    "non-escaped value and comma" : {
                        test : "abc,", 
                        expected : {tokens:[0,3,4],index:4,reminder:""}, 
                        code:tokenize
                    },
                    "comma and non-escaped value" : {
                        test : ",def", 
                        expected : {tokens:[0,1,4],index:4,reminder:""}, 
                        code:tokenize
                    },
                    "escaped value and comma" : {
                        test : "\"zxc\",", 
                        expected : {tokens:[0,5,6],index:6,reminder:""}, 
                        code:tokenize
                    },
                    "escaped value with doule quote and comma" : {
                        test : "\"zx\"\"cd\",", 
                        expected : {tokens:[0,8,9],index:9,reminder:""}, 
                        code:tokenize
                    },
                    "CR" : {
                        test : "\rabc", 
                        expected : {tokens:[0,1,4],index:4,reminder:""}, 
                        code:tokenize
                    },
                    "LF" : {
                        test : "\nabc", 
                        expected : {tokens:[0,1,4],index:4,reminder:""}, 
                        code:tokenize
                    },
                    "CSV to tokens" : {
                        test : "a,b\r\nd,e", 
                        expected : {tokens:[0,1,2,3,4,5,6,7,8],index:8,reminder:""}, 
                        code:tokenize
                    },
                    "unescaped CSV to data" : {
                        test : "a,b,c\r\nd,e,f", 
                        expected : {data:[["a","b","c"],["d","e","f"]], errors:[], warnings:[]}, 
                        code:jsCSV.parse
                    },
                    "escaped CSV to data" : {
                        test : "a,\"b\",c\r\n\"d\",\"e\",f", 
                        expected : {data:[["a","b","c"],["d","e","f"]], errors:[], warnings:[]}, 
                        code:jsCSV.parse
                    },
                    "escaped CSV with quotes to data" : {
                        test : "\"\"\"a\"\"\",\"b\",c\r\n\"\"\"\"\"d\",\"e\",f", 
                        expected : {data:[["\"a\"","b","c"],["\"\"d","e","f"]], errors:[], warnings:[]}, 
                        code:jsCSV.parse
                    },
                    "escaped CSV with wrong columns" : {
                        test : "\"\"\"a\"\"\",\"b\",c\r\n\"\"\"\"\"d\",\"e\"", 
                        expected : {data:[["\"a\"","b","c"],["\"\"d","e"]], 
                                        errors:[
                                            {message: "unexpected number of columns: 2, expected: 3!"}
                                            ], 
                                        warnings:[]}, 
                        code:jsCSV.parse
                    }
                };
                for (k in tests){
                    deepEqual( tests[k].code(tests[k].test), tests[k].expected, k );
                }
        }
    };
    testsLib.push(test); //comment this line to remove from the test
})();

(function (){
    var test = { 
        name : "jsCSV procedural interface test - buffered operations",
        code : function (){

            var testCSV = "\"a,b\"";
            var csv = jsCSV.open();
            deepEqual(csv, { 
                           data : [], errors : [], warnings : [], 
                           prev: undefined, error:undefined, warning:undefined,
                           cols : 0, pos : 0, record:[]
                           },"open csv");
            jsCSV.write(csv, testCSV.slice(0,1));
            deepEqual(csv, { 
                           data : [], errors : [], warnings : [], 
                           prev: undefined, 
                           error:undefined, 
                           warning:undefined,
                           cols : 0, pos : 0, record:[], input:{ 
                               buffer:"\"", index:0, reminder:"\"", tokens:[]
                               }
                           },"write first character");
            jsCSV.write(csv, testCSV.slice(1,2));
            deepEqual(csv, { 
                           data : [], errors : [], warnings : [], 
                           prev: undefined, 
                           error:undefined, 
                           warning:undefined,
                           cols : 0, pos : 0, record:[], input:{ 
                               buffer:"\"a", index:0, reminder:"\"a", tokens:[]
                               }
                           },"write second character");

        }
    };
    testsLib.push(test); //comment this line to remove from the test
})();    

(function (){
    var test = { 
        name : "test CSVGen",
        code : function (){


                var unescapedTestData = (function(n){
                    var data = [];
                    for (var i=0;i<n;++i){data.push(jsCSVTester.genRandomText(20));}
                    return data; 
                })(100); 

                var escapedTestData = (function(d){
                    var data = [];
                    for (var i=0;i<d.length;++i){data.push(jsCSVTester.escapeText(d[i]));}
                    return data; 
                })(unescapedTestData); 

                var escapingTestData = (function(d){
                    var data = [];
                    for (var i=0;i<d.length;++i){data.push(jsCSVTester.unescapeText(d[i]));}
                    return data; 
                })(escapedTestData); 

                deepEqual(escapingTestData, unescapedTestData, "escaping test");

                var testCSV = jsCSVTester.genCSV(50,[10,"firstName","lastName","favoriteCar","favoriteColors"]);

                var expected = jsCSV.parse(testCSV).data;

                var csv = jsCSV.open();
                for(var i=0; i < testCSV.length; ++i){
                    jsCSV.write(csv,testCSV.slice(i,i+1));
                }
                var resultP = jsCSV.close(csv).data;
                deepEqual (resultP, expected, "csv parsing");

                var resultOO = undefined;
                var csvp = new jsCSV(function(data){resultOO = data;});
                for(var i=0; i < testCSV.length; ++i){
                    csvp.write(testCSV.slice(i,i+1));
                }
                csvp.close();
                deepEqual (resultOO, expected, "csv buffered OO parsing");
            }
    };
    testsLib.push(test); //comment this line to remove from the test
})();   

(function (){
    var test = { 
        name : "jsCSV OO interface test",
        code : function (){

                var testCSV = "a,b,c\r\nd,e,f";
                var result = undefined;
                var csvp = new jsCSV(function(data){result = data;});
                csvp.write(testCSV);
                csvp.close();
                deepEqual (result, [["a","b","c"],["d","e","f"]], "csv parsing");
            }
    };
    testsLib.push(test); //comment this line to remove from the test
})();   

(function (){
    var test = { 
        name : "test async",
        code : function (){
                var testCSV = jsCSVTester.genCSV(100,[10,"firstName","lastName","favoriteCar","favoriteColors"]);
                var expected = jsCSV.parse(testCSV).data;
                stop();
                var result = undefined;
                jsCSV.parse(testCSV, function(data){
                    result = data;
                    start();
                    deepEqual (result, expected, "asyn csv parsing");
                });
            }
    };
    testsLib.push(test); //comment this line to remove from the test
})();   

(function (){
    var test = { 
        name : "test both OO and procedural",
        code : function (){

                var testCSV = jsCSVTester.genCSV(50,[10,"firstName","lastName","favoriteCar","favoriteColors"]);
               
                var result = null;
                var csvp = new jsCSV(function(data){result=data;});
                csvp.write(testCSV);
                csvp.close();

                var expected = (jsCSV.parse(testCSV)).data;

                deepEqual (result, expected, "csv parsing: the same data");
            }
    };
    testsLib.push(test); //comment this line to remove from the test
})();   

